#include <rtthread.h>
#include <drivers/usb_host.h>

struct urb* rt_usbh_urb_alloc(unsigned bufsize, urbcomp_t cb)
{
    struct urb *urb;
    int align;

    if ((bufsize > (1024 * 64)) || !cb)
        return RT_NULL;

    align = RT_ALIGN(sizeof(struct urb), 4);
    urb = rt_malloc(align + bufsize);
    if (urb)
    {
        rt_memset(urb, 0, align);
        rt_list_init(&urb->list);
        urb->comp_cb = cb;

        if (bufsize)
        {
            urb->buf = (void*)(((char*)urb) + align);
            urb->bufsize = bufsize;
        }
    }

    return urb;
}

void rt_usbh_urb_free(struct urb *r)
{
    rt_free(r);
}

int rt_usbh_urb_submit(struct uinstance *dev, struct upipe *pipe, struct urb *r)
{
    int ret;

	if (!r || !r->comp_cb)
		return -EINVAL;

    r->actual_size = 0;
    r->status = 0;
    r->is_working = 0;

    ret = rt_usb_hcd_urb_submit(dev->hcd, pipe, r);
    return ret;
}

int rt_usbh_urb_kill(struct uinstance *dev, struct upipe *pipe, struct urb *r)
{
    rt_usb_hcd_urb_cancel(dev->hcd, pipe, r);
    rt_usb_hcd_event_urb_complete(r, -ENOENT);

    return 0;
}
